(function () {

  var btnStatus = "UNDEFINED"; // "UNDEFINED" "CONNECTING" "OPEN" "CLOSING" "CLOSED"

  const btnControl = document.getElementById("voice-record-btn");
  const labelControl = document.getElementById("voice-record-label");
  const chatMessage = document.getElementById("chat-message");
  var preChatMessage="";
  const labelMsg = "点击即可语音聊天"

  const recorder = new RecorderManager("../../dist");

  // 配置录音参数
  const recorderConfig = {
    duration: 60000,       // 最大录音时长60秒（单位ms）
    sampleRate: 16000,     // 采样率
    numberOfChannels: 1,   // 单声道
    encodeBitRate: 48000,  // 编码码率
    format: 'PCM',         // 音频格式
    frameSize: 20,// 帧大小(ms)
    voiceDetect: false // 明确禁用静音检测
  };

  recorder.onStart = () => {
    changeBtnStatus("OPEN");
  }
  let iatWS;
  let resultText = "";
  let resultTextTemp = "";
  let countdownInterval;
  let btnTrueFlag = false;

  /**
   * 获取websocket url
   * 该接口需要后端提供，这里为了方便前端处理
   */
  function getWebSocketUrl() {
    // 请求地址根据语种不同变化
    var url = "wss://iat-api.xfyun.cn/v2/iat";
    var host = "iat-api.xfyun.cn";
    var apiKey = API_KEY;
    var apiSecret = API_SECRET;
    var date = new Date().toGMTString();
    var algorithm = "hmac-sha256";
    var headers = "host date request-line";
    var signatureOrigin = `host: ${host}\ndate: ${date}\nGET /v2/iat HTTP/1.1`;
    var signatureSha = CryptoJS.HmacSHA256(signatureOrigin, apiSecret);
    var signature = CryptoJS.enc.Base64.stringify(signatureSha);
    var authorizationOrigin = `api_key="${apiKey}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"`;
    var authorization = btoa(authorizationOrigin);
    url = `${url}?authorization=${authorization}&date=${date}&host=${host}`;
    return url;
  }

  function toBase64(buffer) {
    var binary = "";
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
      binary += String.fromCharCode(bytes[i]);
    }
    return window.btoa(binary);
  }

  function countdown() {
    let seconds = 60;
    labelControl.innerText = `实时聊天中（${seconds}s）`;
     countdownInterval = setInterval(() => {
      seconds = seconds - 1;
      if (seconds <= 0) {
        clearInterval(countdownInterval);
        recorder.stop();
        closeBtn();

        labelControl.innerText = labelMsg;
      } else {
        labelControl.innerText = `实时聊天中（${seconds}s）`;
      }
    }, 1000);
  }

  function changeBtnStatus(status) {
    btnStatus = status;
    if (status === "CONNECTING") {
      labelControl.innerText = "建立连接中";
      chatMessage.innerText = "";
      resultText = "";
      resultTextTemp = "";
    } else if (status === "OPEN") {
      console.log("open")
      countdown();
    } else if (status === "CLOSING") {
      labelControl.innerText = labelMsg

    } else if (status === "CLOSED") {
      // labelControl.innerText = "开始录音";
    }
  }


  function filterPreviousTextEnhanced(currentText, previousText) {
    if (!currentText || !previousText) return currentText;

    // 标准化文本（去除多余空格和标点差异）
    const normalize = text => text.replace(/\s+/g, '').replace(/[，。、；：？！]/g, '');

    const normCurrent = normalize(currentText);
    const normPrevious = normalize(previousText);

    // 如果当前文本以上一文本开头
    if (normCurrent.startsWith(normPrevious)) {
      // 精确计算原始字符串中的位置
      const rawIndex = findRawPosition(currentText, previousText);
      return currentText.slice(rawIndex).trim();
    }

    // 按句子分割处理
    const sentenceSplit = /([。！？；\n]|\.\s)/; // 包括换行和英文句点
    const prevSentences = previousText.split(sentenceSplit).filter(s => s.trim().length > 0);
    const currSentences = currentText.split(sentenceSplit).filter(s => s.trim().length > 0);

    let matchCount = 0;
    for (let i = 0; i < Math.min(prevSentences.length, currSentences.length); i++) {
      if (normalize(prevSentences[i]) === normalize(currSentences[i])) {
        matchCount++;
      } else {
        break;
      }
    }

    if (matchCount > 0) {
      return currSentences.slice(matchCount).join('').trim();
    }

    return currentText;
  }

// 辅助函数：在原始文本中找到匹配位置
  function findRawPosition(source, target) {
    let index = 0;
    while (index + target.length <= source.length) {
      if (source.slice(index, index + target.length) === target) {
        return index + target.length;
      }
      index++;
    }
    return 0;
  }

  function renderResult(resultData) {
    // 识别结束
    let jsonData = JSON.parse(resultData);
    if (jsonData.data && jsonData.data.result) {
      let data = jsonData.data.result;
      console.log("renderResult", data)
      let str = "";
      let ws = data.ws;
      for (let i = 0; i < ws.length; i++) {
        str = str + ws[i].cw[0].w;
      }
      // 开启wpgs会有此字段(前提：在控制台开通动态修正功能)
      // 取值为 "apd"时表示该片结果是追加到前面的最终结果；取值为"rpl" 时表示替换前面的部分结果，替换范围为rg字段
      if (data.pgs) {
        if (data.pgs === "apd") {
          // 将resultTextTemp同步给resultText
          resultText = resultTextTemp;
        }
        // 将结果存储在resultTextTemp中
        resultTextTemp = resultText + str;
      } else {
        resultText = resultText + str;
      }
      let ret= resultTextTemp || resultText || ""
      let newRet = filterPreviousTextEnhanced(ret,preChatMessage)
      chatMessage.innerText = newRet
      console.log("renderResult", resultTextTemp || resultText)

      //
      // setTimeout(() => {
      //
      //   if (result) {
      //     try {
      //       // 发送识别的文本
      //       fetch('/human', {
      //         body: JSON.stringify({
      //           text: result,
      //           type: 'chat',
      //           interrupt: true,
      //           sessionid: parseInt(document.getElementById('sessionid').value),
      //         }),
      //         headers: {
      //           'Content-Type': 'application/json'
      //         },
      //         method: 'POST'
      //       });
      //     }catch (e) {
      //         showErrorModal("大模型接口（/human）, 异常")
      //     }
      //
      //     addChatMessage(result, 'user');
      //     $('#chat-message').val('');
      //
      //   }
      // }, 1000);

    }
    if (jsonData.code === 0 && jsonData.data.status === 2) {
      iatWS.close();
    }
    if (jsonData.code !== 0) {
      iatWS.close();
      console.error(jsonData||"");
    }
  }


  function connectWebSocket() {
    try{
      const websocketUrl = getWebSocketUrl();
      if ("WebSocket" in window) {
        iatWS = new WebSocket(websocketUrl);
      } else if ("MozWebSocket" in window) {
        iatWS = new MozWebSocket(websocketUrl);
      } else {
        showErrorModal("浏览器不支持WebSocket")
        return;
      }
      startBtn();
      changeBtnStatus("CONNECTING");
      iatWS.onopen = (e) => {
        // 开始聊天
        recorder.start(recorderConfig);
        var params = {
          common: {
            app_id: APPID,
          },
          business: {
            language: "zh_cn",
            domain: "iat",
            accent: "mandarin",
            vad_eos: 60000,
            dwa: "wpgs",
          },
          data: {
            status: 0,
            format: "audio/L16;rate=16000",
            encoding: "raw",
          },
        };
        iatWS.send(JSON.stringify(params));
      };
      iatWS.onmessage = (e) => {
        renderResult(e.data);
      };
      iatWS.onerror = (e) => {
        console.error("iatWS.onerror", e);
        recorder.stop();
        changeBtnStatus("CLOSED");
      };
      iatWS.onclose = (e) => {
        console.log("iatWS.onclose", e);
        recorder.stop();
        changeBtnStatus("CLOSED");
      };
    }catch (e) {
      showErrorModal(e.message)
      closeBtn()
    }

  }

  function closeBtn(){
    clearInterval(countdownInterval);
    $('#voice-record-btn').removeClass('recording-pulse');
    $('#voice-record-btn').css('background-color', '');
    labelControl.innerText = labelMsg;
    // btnStatus = "CLOSED"
  }

  function startBtn(){
    $('#voice-record-btn').addClass('recording-pulse');
    $('#voice-record-btn').css('background-color', '#dc3545');
  }

  let lastFrameSent = false;
  recorder.onFrameRecorded = ({ isLastFrame, frameBuffer }) => {
    console.log("recorder.onFrameRecorded")
    if (iatWS.readyState === iatWS.OPEN) {
      iatWS.send(
          JSON.stringify({
            data: {
              status: 1,
              format: "audio/L16;rate=16000",
              encoding: "raw",
              audio: toBase64(frameBuffer),
            },
          })
      );
      if (isLastFrame) {
        lastFrameSent = true;
      }
    }
  };
  recorder.onStop = () => {
    console.log("recorder.onStop")

    if (iatWS.readyState === iatWS.OPEN && lastFrameSent) {
      // 60秒超时后才发送结束标志
      setTimeout(() => {
        iatWS.send(JSON.stringify({
          data: {
            status: 2,
            format: "audio/L16;rate=16000",
            encoding: "raw",
            audio: "",
          }
        }));
        changeBtnStatus("CLOSING");
      }, 60000 ); // 剩余时间
    }
    closeBtn();

  };


  // 按钮事件
  btnControl.addEventListener('click', function() {
    btnTrueFlag = !btnTrueFlag
    // btnTrueFlag = (btnStatus === "CONNECTING" || btnStatus === "OPEN")?false:btnTrueFlag

    if (btnStatus === "UNDEFINED" || btnStatus === "CLOSED") {
      connectWebSocket();
    } else if (btnStatus === "CONNECTING" || btnStatus === "OPEN") {
      // 结束录音
      recorder.stop();
      labelControl.innerText = labelMsg;
      chatMessage.innerText = ""
    }
    if (btnTrueFlag){
      // startBtn()
    }else{
      closeBtn()
      btnStatus = "UNDEFINED"
    }
  });

  function showErrorModal(message) {
    // 如果已存在则先移除
    $('#dynamicErrorModal').remove();

    // 动态创建模态框HTML
    const modalHtml = `
    <div class="modal fade" id="dynamicErrorModal" tabindex="-1">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header bg-danger text-white">
            <h5 class="modal-title">错误提示</h5>
            <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
          </div>
          <div class="modal-body">
            ${message}
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
          </div>
        </div>
      </div>
    </div>
  `;

    // 添加到body并显示
    $('body').append(modalHtml);
    const modal = new bootstrap.Modal('#dynamicErrorModal');
    modal.show();

    // 模态框关闭后自动移除
    $('#dynamicErrorModal').on('hidden.bs.modal', function() {
      $(this).remove();
    });
  }


  // btnControl.onclick = function () {
  //   if (btnStatus === "UNDEFINED" || btnStatus === "CLOSED") {
  //     connectWebSocket();
  //   } else if (btnStatus === "CONNECTING" || btnStatus === "OPEN") {
  //     // 结束录音
  //     recorder.stop();
  //   }
  // };


  // 文字-----------------------------------------------------------------------------------------------------------------------------------------------------
    //2wkRNGVRSY9g0TnEgiupcBzGhW5_3REQ8DqjUa7z1STdpRr9t
    $('#video-size-slider').on('input', function() {
      const value = $(this).val();
      $('#video-size-value').text(value + '%');
      $('#video').css('width', value + '%');
    });
    function updateConnectionStatus(status) {
      const statusIndicator = $('#connection-status');
      const statusText = $('#status-text');

      statusIndicator.removeClass('status-connected status-disconnected status-connecting');

      switch(status) {
        case 'connected':
          statusIndicator.addClass('status-connected');
          statusText.text('已连接');
          break;
        case 'connecting':
          statusIndicator.addClass('status-connecting');
          statusText.text('连接中...');
          break;
        case 'disconnected':
        default:
          statusIndicator.addClass('status-disconnected');
          statusText.text('未连接');
          break;
      }
    }

    // 添加聊天消息
    function addChatMessage(message, type = 'user') {
      const messagesContainer = $('#chat-messages');
      const messageClass = type === 'user' ? 'user-message' : 'system-message';
      const sender = type === 'user' ? '您' : '数字人';

      const messageElement = $(`
                    <div class="asr-text ${messageClass}">
                        ${sender}: ${message}
                    </div>
                `);

      messagesContainer.append(messageElement);
      messagesContainer.scrollTop(messagesContainer[0].scrollHeight);
    }

    // 开始/停止按钮
    $('#start').click(function() {
      updateConnectionStatus('connecting');
      start();
      $(this).hide();
      $('#stop').show();

      // 添加定时器检查视频流是否已加载
      let connectionCheckTimer = setInterval(function() {
        const video = document.getElementById('video');
        // 检查视频是否有数据
        if (video.readyState >= 3 && video.videoWidth > 0) {
          updateConnectionStatus('connected');
          clearInterval(connectionCheckTimer);
        }
      }, 2000); // 每2秒检查一次

      // 60秒后如果还是连接中状态，就停止检查
      setTimeout(function() {
        if (connectionCheckTimer) {
          clearInterval(connectionCheckTimer);
        }
      }, 60000);
    });

    $('#stop').click(function() {
      stop();
      $(this).hide();
      $('#start').show();
      updateConnectionStatus('disconnected');
    });

    // 录制功能
    $('#btn_start_record').click(function() {
      console.log('Starting recording...');
      fetch('/record', {
        body: JSON.stringify({
          type: 'start_record',
          sessionid: parseInt(document.getElementById('sessionid').value),
        }),
        headers: {
          'Content-Type': 'application/json'
        },
        method: 'POST'
      }).then(function(response) {
        if (response.ok) {
          console.log('Recording started.');
          $('#btn_start_record').prop('disabled', true);
          $('#btn_stop_record').prop('disabled', false);
          $('#recording-indicator').addClass('active');
        } else {
          console.error('Failed to start recording.');
        }
      }).catch(function(error) {
        console.error('Error:', error);
      });
    });

    $('#btn_stop_record').click(function() {
      console.log('Stopping recording...');
      fetch('/record', {
        body: JSON.stringify({
          type: 'end_record',
          sessionid: parseInt(document.getElementById('sessionid').value),
        }),
        headers: {
          'Content-Type': 'application/json'
        },
        method: 'POST'
      }).then(function(response) {
        if (response.ok) {
          console.log('Recording stopped.');
          $('#btn_start_record').prop('disabled', false);
          $('#btn_stop_record').prop('disabled', true);
          $('#recording-indicator').removeClass('active');
        } else {
          console.error('Failed to stop recording.');
        }
      }).catch(function(error) {
        console.error('Error:', error);
      });
    });

    $('#echo-form').on('submit', function(e) {
      e.preventDefault();
      try {
        var message = $('#message').val();

        if (!message.trim()) return;
        console.log('Sending echo message:', message);
        fetch('/human', {
          body: JSON.stringify({
            text: message,
            type: 'echo',
            interrupt: true,
            sessionid: parseInt(document.getElementById('sessionid').value),
          }),
          headers: {
            'Content-Type': 'application/json'
          },
          method: 'POST'
        });

        $('#message').val('');
        addChatMessage(`已发送朗读请求: "${message}"`, 'system');
      }catch (e){
        console.log("$('#echo-form')",e)
      }

    });

    // 聊天模式表单提交
    $('#chat-form').on('submit', function(e) {
      e.preventDefault();
      var message = $('#chat-message').val();
      if (!message.trim()) return;

      console.log('Sending chat message:', message);

      fetch('/human', {
        body: JSON.stringify({
          text: message,
          type: 'chat',
          interrupt: true,
          sessionid: parseInt(document.getElementById('sessionid').value),
        }),
        headers: {
          'Content-Type': 'application/json'
        },
        method: 'POST'
      });

      addChatMessage(message, 'user');
      preChatMessage += message
      chatMessage.innerText = ""
      resultText = ""
    });

    // 按住说话功能
    let mediaRecorder;
    let audioChunks = [];
    let isRecording = false;
    let recognition;

    // 检查浏览器是否支持语音识别
    const isSpeechRecognitionSupported = 'webkitSpeechRecognition' in window || 'SpeechRecognition' in window;


    if (isSpeechRecognitionSupported) {
      recognition = new (window.SpeechRecognition  || window.webkitSpeechRecognition)();

      recognition.continuous = true;  // 设置连续识别
      recognition.interimResults = true;  // 获取中间结果
      recognition.lang = 'zh-CN';



      // recognition.onresult = function(event) {
      //   alert('onresult');
      //   let interimTranscript = '';
      //   let finalTranscript = '';
      //
      //   for (let i = event.resultIndex; i < event.results.length; ++i) {
      //     if (event.results[i].isFinal) {
      //       finalTranscript += event.results[i][0].transcript;
      //     } else {
      //       interimTranscript += event.results[i][0].transcript;
      //       //alert('chat-message'+ JSON.stringify(interimTranscript));
      //       $('#chat-message').val(interimTranscript);
      //     }
      //   }
      //
      //   if (finalTranscript) {
      //     //alert('chat-message'+ JSON.stringify(finalTranscript));
      //     $('#chat-message').val(finalTranscript);
      //   }
      // };




      recognition.onerror = function(event) {
        alert('语音识别错误'+ JSON.stringify(event));
        console.error('语音识别错误:', event.error);
      };
    }

    //
    // $('#voice-record-btn').on('mousedown touchstart', function(e) {
    //     e.preventDefault();
    //     startRecording();
    // }).on('mouseup mouseleave touchend', function() {
    //     if (isRecording) {
    //         stopRecording();
    //     }
    // });

    // 开始录音
    function startRecording() {
      if (isRecording) return;
      try{
        navigator.mediaDevices.getUserMedia({ audio: true })
            .then(function(stream) {
              audioChunks = [];
              mediaRecorder = new MediaRecorder(stream);

              mediaRecorder.ondataavailable = function(e) {
                if (e.data.size > 0) {
                  audioChunks.push(e.data);
                }
              };

              mediaRecorder.start();
              isRecording = true;

              $('#voice-record-btn').addClass('recording-pulse');
              $('#voice-record-btn').css('background-color', '#dc3545');

              if (recognition) {
                setTimeout(() => {
                  recognition.start();
                }, 500);
                // recognition.start();
              }
            })
            .catch(function(error) {
              alert('无法访问麦克风:22'+ JSON.stringify(error.message));
              //alert('无法访问麦克风，请检查浏览器权限设置。');
            });
      }catch(error) {
        alert('无法访问麦克风:22'+ JSON.stringify(error.message));

      };



    }

    function stopRecording() {
      if (!isRecording) return;

      mediaRecorder.stop();
      isRecording = false;

      // 停止所有音轨
      mediaRecorder.stream.getTracks().forEach(track => track.stop());

      // 视觉反馈恢复
      $('#voice-record-btn').removeClass('recording-pulse');
      $('#voice-record-btn').css('background-color', '');

      // 停止语音识别
      if (recognition) {

        recognition.stop();
      }

      // 获取识别的文本并发送
      // setTimeout(function() {
      //
      //   const recognizedText = $('#chat-message').val().trim();
      //   //alert('文本'+ JSON.stringify(recognizedText));
      //
      //   if (recognizedText) {
      //     // 发送识别的文本
      //     fetch('/human', {
      //       body: JSON.stringify({
      //         text: recognizedText,
      //         type: 'chat',
      //         interrupt: true,
      //         sessionid: parseInt(document.getElementById('sessionid').value),
      //       }),
      //       headers: {
      //         'Content-Type': 'application/json'
      //       },
      //       method: 'POST'
      //     });
      //
      //     addChatMessage(recognizedText, 'user');
      //     $('#chat-message').val('');
      //   }
      // }, 500);
    }

    // WebRTC 相关功能
    if (typeof window.onWebRTCConnected === 'function') {
      const originalOnConnected = window.onWebRTCConnected;
      window.onWebRTCConnected = function() {
        updateConnectionStatus('connected');
        if (originalOnConnected) originalOnConnected();
      };
    } else {
      window.onWebRTCConnected = function() {
        updateConnectionStatus('connected');
      };
    }

    // 当连接断开时更新状态
    if (typeof window.onWebRTCDisconnected === 'function') {
      const originalOnDisconnected = window.onWebRTCDisconnected;
      window.onWebRTCDisconnected = function() {
        updateConnectionStatus('disconnected');
        if (originalOnDisconnected) originalOnDisconnected();
      };
    } else {
      window.onWebRTCDisconnected = function() {
        updateConnectionStatus('disconnected');
      };
    }

    // SRS WebRTC播放功能
    var sdk = null; // 全局处理器，用于在重新发布时进行清理

    function startPlay() {
      // 关闭之前的连接
      if (sdk) {
        sdk.close();
      }

      sdk = new SrsRtcWhipWhepAsync();
      $('#video').prop('srcObject', sdk.stream);

      var host = window.location.hostname;
      var url = "http://" + host + ":1985/rtc/v1/whep/?app=live&stream=livestream";

      sdk.play(url).then(function(session) {
        console.log('WebRTC播放已启动，会话ID:', session.sessionid);
      }).catch(function(reason) {
        sdk.close();
        console.error('WebRTC播放失败:', reason);
      });
    }
})();
